fn destroy_box(c: Box<i32>) {
    println!("Destroying a box that contains {}", c);

    // c is destroyed and memory freed
}


fn base() {
    let x = 5u32; // stack integer

    let y = x;  // copy x to y

    println!("x is {}, and y is {}", x, y);


    let a = Box::new(5_i32);
    println!("a contains: {}", a);

    let b = a; // move a to b;  a is useless
    // println!("a contains: {}", a); // Error: a can no longer access the data;
    
    destroy_box(b);
    //println!("b contains: {}", b); // ownership of b is moved to destroy_box 's paramters
}


fn mutability(){
    let imm_box = Box::new(5_u32);
    println!("imm box contains {}", imm_box);


    let mut mut_box = imm_box; // move ownership from imm_box to mut_box;

    *mut_box = 4;
    println!("mut_box now contains {}", mut_box);
}




fn partial_moves(){
    #[derive(Debug)]
    struct Person {
        name: String,
        age: Box<u8>,
    }

    let mut person = Person {
        name: String::from("Alice"),
        age: Box::new(20),
    };

    let Person { name, ref age } = person; // name is move from person.name into destructing name

    println!("age is {}, name is {}", age, name);

    //println!("The person struct is {:?}", person); // person have no ownership of name , Error
    
    println!("The person's age from person struct is {}", person.age); // age is reference to person.age; 

    //move new value to person.name
    person.name = String::from("Bob");
    println!("The person struct is {:?}", person);

}

pub fn main(){
    base();
    mutability();
    partial_moves();
}
